home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / tidy-1.000 / tidy-1 / tidy-1.0 / tidy < prev   
Encoding:
Text File  |  1996-03-14  |  17.3 KB  |  710 lines

  1. #!/usr/local/bin/perl
  2.  
  3. #-----------------------------------------------------------------------
  4. # Tidy Version 1.0
  5. #
  6. # Tidy up logfile(s) created by syslogd
  7. #
  8. # See manual pages tidy(8) and tidy.conf(5) for details
  9. #
  10. # Author: Marek Rouchal, University of Bayreuth, Germany
  11. #         (marek@saftsack.fs.uni-bayreuth.de)
  12. #-----------------------------------------------------------------------
  13.  
  14. #----------------------
  15. # Configuration
  16. #----------------------
  17.  
  18. require 5.0; # tidy needs at least perl5
  19.  
  20. # This is where tidy looks for its configuration.
  21. # This may be overridden by the -C option
  22. # All other configurable options are found there
  23. $CONFIGFILE = "tidy.conf";
  24.  
  25. #----------------------
  26. # parse command line
  27. #----------------------
  28.  
  29. # hot pipe output, flush after each print
  30. $| = 1;
  31.  
  32. $NOTIDY = 0;
  33. $VERBOSE = 1;
  34.  
  35. #--------------------
  36. # look for switches
  37. #--------------------
  38. while ( $ARGV[0] ) {
  39.     $_ = shift( @ARGV );
  40.     #------------------
  41.     # the '-' switches
  42.     #------------------
  43.     if ( /^-/ ) {
  44.         @_ = split ( //, $_ );
  45.         shift ( @_ );
  46.         foreach ( @_ ) {
  47.             if ( "$_" eq "a" )
  48.                 { $OUTPUT = "ascii"; }
  49.             elsif ( "$_" eq "B" ) {
  50.                 $_ = shift( @ARGV );
  51.                 ($DBFILE) = /^(.+)$/ unless ( /^(-|\+)/ );
  52.                 die "tidy: error: No database file specified\n" unless $DBFILE;
  53.                 }
  54.             elsif ( "$_" eq "b" )
  55.                 { $ORIENTATION = "below"; }
  56.             elsif ( "$_" eq "C" ) {
  57.                 $_ = shift( @ARGV );
  58.                 ($CONFIGFILE) = /^(.+)$/ unless ( /^(-|\+)/ );
  59.                 die "tidy: error: No configuration file specified\n"
  60.                     unless $CONFIGFILE;
  61.                 }
  62.             elsif ( "$_" eq "c" )
  63.                 { $CASE_SENSITIVE = "on"; }
  64.             elsif ( "$_" eq "D" )
  65.                 { $FORM_DATE = "long"; }
  66.             elsif ( "$_" eq "d" )
  67.                 { $FORM_DATE = "short"; }
  68.             elsif ( "$_" eq "H" )
  69.                 { $OUTPUT = "html"; }
  70.             elsif ( "$_" eq "h" )
  71.                 { &help_screen; exit 0; }
  72.             elsif ( "$_" eq "L" ) {
  73.                 $_ = shift( @ARGV );
  74.                 ($LOGFILE) = /^(.+)$/ unless ( /^(-|\+)/ );
  75.                 die "tidy: error: No log file specified\n" unless $LOGFILE;
  76.                 }
  77.             elsif ( "$_" eq "O" )
  78.                 { $NOTIDY = 1; }
  79.             elsif ( "$_" eq "o" ) {
  80.                 $_ = shift( @ARGV );
  81.                 ($OUTFILE) = /^(.+)$/ unless ( /^(-|\+)/ );
  82.                 die "tidy: error: No output file specified\n" unless $OUTFILE;
  83.                 }
  84.             elsif ( "$_" eq "p" ) {
  85.                 $_ = shift( @ARGV );
  86.                 ($PAGER_LINES) = /^(\d+)$/ unless ( /^(-|\+)/ );
  87.                 die "tidy: error: No number for pager_lines specified\n"
  88.                     unless $PAGER_LINES;
  89.                 }
  90.             elsif ( "$_" eq "q" )
  91.                 { $VERBOSE = 0; }
  92.             elsif ( "$_" eq "r" )
  93.                 { $RULER = "on"; }
  94.             elsif ( "$_" eq "s" ) {
  95.                 $_ = shift( @ARGV );
  96.                 ($SORTKEY) = /^(.+)$/ unless ( /^(-|\+)/ );
  97.                 die "tidy: error: No sortkey specified\n" unless $SORTKEY;
  98.                 }
  99.             elsif ( "$_" eq "T" )
  100.                 { $FORM_TIME = "long"; }
  101.             elsif ( "$_" eq "t" )
  102.                 { $FORM_TIME = "short"; }
  103.             elsif ( "$_" eq "v" )
  104.                 { &version_info; exit 0; }
  105.             else
  106.                 { die "tidy: error: Illegal option \"-$_\" specified\n"; }
  107.             }
  108.         }
  109.     #-------------------
  110.     # the '+' switches
  111.     #-------------------
  112.     elsif ( /^\+/ ) {
  113.         @_ = split ( //, $_ );
  114.         shift ( @_ );
  115.         foreach ( @_ ) {
  116.             if ( "$_" eq "b" )
  117.                 { $ORIENTATION = "besides"; }
  118.             elsif ( "$_" eq "c" )
  119.                 { $CASE_SENSITIVE = "off"; }
  120.             elsif ( "$_" eq "d" )
  121.                 { $FORM_DATE = "none"; }
  122.             elsif ( "$_" eq "O" )
  123.                 { $OUTPUT = "none"; }
  124.             elsif ( "$_" eq "p" )
  125.                 { $PAGER_LINES = "0"; }
  126.             elsif ( "$_" eq "r" )
  127.                 { $RULER = "off"; }
  128.             elsif ( "$_" eq "t" )
  129.                 { $FORM_TIME = "none"; }
  130.             else
  131.                 { die "tidy: error: Illegal option \"+$_\" specified\n"; }
  132.             }
  133.         }
  134.     else
  135.         { die "tidy: error: Runaway argument \"$_\" in command line\n"; }
  136.     }
  137.  
  138. &version_info if $VERBOSE;
  139.  
  140. #-----------------------------
  141. # load configfile
  142. #-----------------------------
  143.  
  144. if ( -f "$CONFIGFILE" ) {
  145.     print "tidy: Reading configuration file \"$CONFIGFILE\"...\n" if $VERBOSE;
  146.     require( "$CONFIGFILE" ) ||
  147.         die "tidy: error: Cannot read \"$CONFIGFILE\".\n";
  148.     }
  149. else
  150.     { die "tidy: error: Configuration file \"$CONFIGFILE\" not found.\n"; }
  151.  
  152. #-----------------------------
  153. # read database
  154. #-----------------------------
  155.  
  156. $TODAY = localtime;
  157.  
  158. if ( -f "$DBFILE" ) {
  159.     print "tidy: Reading database file \"$DBFILE\"...\n" if $VERBOSE;
  160.     require("$DBFILE") ||
  161.         die "tidy: error: Cannot read \"$DBFILE\".\n";
  162.     }
  163. else {
  164.     print "tidy: No database file. \"$DBFILE\" will be created.\n" if $VERBOSE;
  165.     $CREATION_DATE = $TODAY;
  166.     $LAST_UPDATE   = $TODAY;
  167.     }
  168.  
  169. # sort categories
  170. @sort_cat = sort {$CATEGORY{$a}[0] <=> $CATEGORY{$b}[0]} (keys %CATEGORY );
  171.  
  172. if ( $NOTIDY != 1 ) {
  173.     &process_logfile;    
  174.     &write_database;
  175.     &write_logfile;
  176.     }
  177.  
  178. if ( "$OUTPUT" ne "none" ) {
  179.     &init_sort;
  180.     &print_statistics;
  181.     }
  182.  
  183. print "tidy: Done.\n" if $VERBOSE;
  184. exit 0;
  185. #
  186. # and that's ist!!!  *** THE END ***
  187. #
  188.  
  189. sub process_logfile {
  190. #--------------------------
  191. # process logfile
  192. #--------------------------
  193.  
  194. print "tidy: Processing logfile \"$LOGFILE\"... " if $VERBOSE;
  195. open( Logfile, "<$LOGFILE" )
  196.     || die "\b \ntidy: error: cannot open logfile \"$LOGFILE\"\n";
  197.  
  198. # process indicators |/-\
  199. @COUNT_STR = ( "\b|", "\b/", "\b-", "\b\\" );
  200.  
  201. $lines = 0;
  202. # Shall I print process indicator?
  203. $t = $VERBOSE && -t STDOUT;
  204. print "|" if $t;
  205.  
  206. while ( <Logfile> ) {
  207.     chop;
  208.     $count++; $lines++;
  209.     print "$COUNT_STR[ $count &= 3 ]" if $t;
  210.  
  211.     # check for valid entry
  212.     if ( /^(\w+)\s+(\d+)\s+(\d\d:\d\d:\d\d)\s+(\S+)\s+(\S+?)(\[\d+\]|):\s*(.*)$/ ) {
  213.         # The preceding regexp is not a simple one :) Here is what it returns:
  214.         # Month (e.g. "Feb"), is casted to number
  215.         $month = $MONTH_STR_TO_NUM{$1};
  216.         # Day (e.g. "12"), filled with '0'
  217.         $day = sprintf ("%02d",$2);
  218.         # Time (e.g. "10:37:55")
  219.         $time = $3;
  220.         # local host name
  221.         $host = $4;
  222.         # Process which called syslog (e.g. "in.telnetd")
  223.         $proc = $5;
  224.         # its PID in square brackets or nothing (if PID is not logged)
  225.         # (e.g. "[1234]")
  226.         $pid = $6;
  227.         # the message (e.g. "connect from foo.bar.dom")
  228.         $mesg = $7;
  229.  
  230.         $d = 0; # flag; when = 1 then entry will be discarded
  231.  
  232.         # scan all entry types
  233.         foreach $cat ( @sort_cat ) {
  234.             # check for process
  235.             if ( $proc =~ /$CATEGORY{$cat}[1]/ ) {
  236.                 # try to get the remote host
  237.                 if ( $mesg =~ /$CATEGORY{$cat}[2]/ ) {
  238.                     # found entry with remotehost: GOTCHA!
  239.                     $remote = $1;
  240.                     # do hostname aliasing
  241.                     $remote = $HOSTNAME_ALIAS{$remote}
  242.                         if ( exists( $HOSTNAME_ALIAS{$remote} ) );
  243.                     $DB{$remote}{$cat}[0]++;
  244.                     $DB{$remote}{$cat}[1] = join('/', $month, $day);
  245.                     $DB{$remote}{$cat}[2] = $time;
  246.                     # we may discard this line from logfile
  247.                     $d = 1;
  248.                     $LOG_REMOTE++;
  249.                     last; # exit loop for categories
  250.                     }
  251.                 else {
  252.                     # found entry, but no remote host
  253.                     # discard it if it matches the second regexp
  254.                     if ($CATEGORY{$cat}[3] && $mesg =~ /$CATEGORY{$cat}[3]/ ) {
  255.                         # we may discard this line from logfile
  256.                         $d = 1;
  257.                         $LOG_DISCARD++;
  258.                         last; # exit loop for categories
  259.                         }
  260.                     } # END found remote host
  261.                 } # END found category
  262.             } # END loop for categories
  263.         if ( $d == 0 ) {
  264.             # unrecognized entry: save it
  265.             push( @REST, $_ );
  266.             }
  267.         } # END found valid syslog line in logfile
  268.     else {
  269.         # unrecognized string in logfile
  270.         # should usually not occur, but save it nevertheless
  271.         push( @REST, $_ );
  272.         }
  273.     } # END loop for logfile
  274.  
  275. close(Logfile);
  276. print "\b " if $t;
  277. print "$lines lines.\n" if $VERBOSE;
  278. }
  279.  
  280. sub write_database {
  281. #----------------------------
  282. # save database
  283. #----------------------------
  284.  
  285. $LAST_UPDATE   = $TODAY;
  286. open( Database, ">$DBFILE" )
  287.     || die "tidy: error: Cannot open database \"$DBFILE\" for output\n";
  288.  
  289. print "tidy: Writing database file \"$DBFILE\"...\n" if $VERBOSE;
  290.  
  291. print Database <<"EOF";
  292. # Tidy 1.0 Database File
  293. # created $TODAY
  294. # with configfile $CONFIGFILE
  295. #
  296. # This file is automatically created. Editing of this file by hand is strongly
  297. # discouraged unless you are perfectly sure of what you are doing :)
  298. #
  299. \$LAST_UPDATE = \'$LAST_UPDATE\'\;
  300. \$CREATION_DATE = \'$CREATION_DATE\'\;
  301. \$LOG_REMOTE = \'$LOG_REMOTE\'\;
  302. \$LOG_DISCARD = \'$LOG_DISCARD\'\;
  303. #
  304. EOF
  305.  
  306. foreach $host ( keys %DB ) {
  307.     foreach $cat ( keys %{$DB{$host}} ) {
  308.         print Database "\$DB{\'$host\'}{\'$cat\'} = [ $DB{$host}{$cat}[0], \'$DB{$host}{$cat}[1]\', \'$DB{$host}{$cat}[2]\' ]\;\n";
  309.         }
  310.     print Database "#\n";
  311.     }
  312. close(Database);
  313. }
  314.  
  315. sub write_logfile {
  316.     #----------------------------
  317.     # write rest to logfile
  318.     #----------------------------
  319.  
  320.     open( Logfile, ">$LOGFILE" )
  321.         || die "tidy: error: cannot open \"$LOGFILE\" for output\n";
  322.  
  323.     print "tidy: Writing logfile \"$LOGFILE\"... " if $VERBOSE;
  324.  
  325.     $d = 0; # lines counter
  326.     foreach ( @REST ) {
  327.         $d++;
  328.         print Logfile "$_\n";
  329.         }
  330.     close(Logfile);
  331.     print "$d lines left in logfile.\n" if $VERBOSE;
  332.     }
  333.  
  334. sub init_sort {
  335.     #---------------------------
  336.     # initialize sorting
  337.     #---------------------------
  338.     if ( "$SORTKEY" eq "none" )
  339.         { $SORT_FLAG = 0; } # no sorting at all
  340.     elsif ( "$SORTKEY" eq "host" ) {
  341.         $SORT_FLAG = 1; # alphanumerical sorting
  342.         foreach $h ( keys %DB ) {
  343.             if ( "$CASE_SENSITIVE" eq "on" )
  344.                 { $sort_ary{$h} =     $h;   }
  345.             else
  346.                 { $sort_ary{$h} = uc( $h ); }
  347.             }
  348.         }
  349.     elsif ( "$SORTKEY" eq "domain" ) {
  350.         $SORT_FLAG = 1; # alphanumerical sorting
  351.         foreach $h ( keys %DB ) {
  352.             # Perl is _SO_ cool: The following does foo.bar.dom -> dom.bar.foo
  353.             $d = "";
  354.             while ( $h =~ /([\w-]+)(\.|)/g )
  355.                 { $d = $2 . $1 . $d ; }
  356.  
  357.             if ( "$CASE_SENSITIVE" eq "on" )
  358.                 { $sort_ary{$h} =     $d;   }
  359.             else
  360.                 { $sort_ary{$h} = uc( $d ); }
  361.             }
  362.         }
  363.     else {
  364.         $d = 0; # flag = 1 when sortkey found
  365.         foreach $cat ( @sort_cat ) {
  366.             if ( "$SORTKEY" eq "$cat" ) {
  367.                 $SORT_FLAG = 2; # numerical sorting
  368.                 $d = 1;
  369.                 foreach $h ( keys %DB )
  370.                     { $sort_ary{$h} = $DB{$h}{$cat}[0]; }
  371.                 last;
  372.                 }
  373.             }
  374.         die "tidy: error: Illegal SORTKEY \"$SORTKEY\" specified.\n"
  375.             if $d == 0;
  376.         }
  377.     }
  378.  
  379. sub print_statistics {
  380. #----------------------------
  381. # print statisics
  382. #----------------------------
  383.  
  384. if ( "$OUTPUT" eq "ascii" )
  385.     { ( $OUTFILE = $OUTDIR . '/' . $OUTFILE_ASCII ) unless $OUTFILE; }
  386. elsif ( "$OUTPUT" eq "html" )
  387.     { ( $OUTFILE = $OUTDIR . '/' . $OUTFILE_HTML ) unless $OUTFILE; }
  388. else
  389.     { die "tidy: error: Illegal output format \"$OUTPUT\" specified.\n"; }
  390.  
  391. print "tidy: Writing output to \"$OUTFILE\"...\n" if $VERBOSE;
  392.  
  393. open(Statfile,">$OUTFILE")
  394.     || die "tidy: error: cannot open \"$OUTFILE\" for output\n";
  395.  
  396. if ( $SORT_FLAG == 0 ) {
  397.     # no sorting
  398.     @sorted_hosts = keys %DB;
  399.     }
  400. elsif ( $SORT_FLAG == 1 ) {
  401.     # alphanumerical sort, a's first, z's last
  402.     @sorted_hosts = sort { $sort_ary{$a} cmp $sort_ary{$b} } ( keys %DB );
  403.     }
  404. elsif ($SORT_FLAG == 2) {
  405.     # numerical sort, highest numbers first
  406.     @sorted_hosts = sort { $sort_ary{$b} <=> $sort_ary{$a} } ( keys %DB );
  407.     }
  408.  
  409. #--------------------
  410. # header, init
  411. #--------------------
  412.  
  413. # total number of remote hosts
  414. $TOTAL_REMOTE = keys %DB;
  415.  
  416. if ( "$OUTPUT" eq "ascii" ) {
  417.     #---------------------
  418.     # ascii header & init
  419.     #---------------------
  420.     foreach ( @ASCII_HEADER ) {
  421.         eval "\$h = \"$_\";";
  422.         print Statfile "$h\n";
  423.         }
  424.  
  425.     $LEN = '4';
  426.     $rule_part = '+----';
  427.     if ( "$ORIENTATION" eq "below" ) {
  428.         if ( "$FORM_DATE" eq "short" || "$FORM_TIME" eq "short" )
  429.             { $LEN = '5'; $rule_part = '+-----'; }
  430.         if ( "$FORM_DATE" eq "long" )
  431.             { $LEN = '6'; $rule_part = '+------'; }
  432.         if ( "$FORM_TIME" eq "long" )
  433.             { $LEN = '8'; $rule_part = '+--------'; }
  434.         }
  435.     else { # ORIENTATION "besides"
  436.         if ( "$FORM_TIME" eq "long" )
  437.             { $LEN += 9; $rule_part .= '---------'; }
  438.         if ( "$FORM_DATE" eq "long" && "$FORM_TIME" ne "long" )
  439.             { $LEN += 7; $rule_part .= '-------'; }
  440.         if ( "$FORM_DATE" eq "short" && "$FORM_TIME" ne "long" )
  441.             { $LEN += 6; $rule_part .= '------'; }
  442.         if ( "$FORM_TIME" eq "short" && "$FORM_DATE" eq "none" )
  443.             { $LEN += 6; $rule_part .= '------'; }
  444.         }
  445.     # compose table header
  446.     $rule = '';
  447.     $cat_s = '';
  448.     foreach $cat ( @sort_cat ) {
  449.         $rule .= $rule_part;
  450.         $cat_s .= sprintf ( "|%${LEN}.${LEN}s", $CATEGORY{$cat}[4] );
  451.         }
  452.     $rule .= '+';
  453.     $cat_s .= '| Remote Host';
  454.     while ( length ($rule) < 79 ) # fill up with '-'
  455.         { $rule .= '-'; }
  456.     }
  457. else {
  458.     #---------------------
  459.     # html header & init
  460.     #---------------------
  461.     foreach ( @HTML_HEADER ) {
  462.         eval "\$h = \"$_\";";
  463.         print Statfile "$h\n";
  464.         }
  465.     }
  466.  
  467. #--------------------
  468. # print entries
  469. #--------------------
  470.  
  471. $count = 0;
  472. if ( "$OUTPUT" eq "ascii" ) {
  473.     #--------------------
  474.     # ascii output
  475.     #--------------------
  476.     if ( $RULER eq "on" )
  477.         { print Statfile "$rule\n"; }
  478.  
  479.     foreach $host ( @sorted_hosts ) {
  480.         if ( $count == 0 ) {
  481.             if ( $RULER eq "on" )
  482.                 { print Statfile "$cat_s\n$rule\n"; }
  483.             else
  484.                 { print Statfile "$rule\n$cat_s\n$rule\n"; }
  485.  
  486.             if ( $PAGER_LINES )
  487.                 { $count = -$PAGER_LINES; }
  488.             }
  489.         $count++;
  490.  
  491.         if ( "$ORIENTATION" eq "below" ) {
  492.             $e = ''; $t = ''; $d = '';
  493.             foreach $cat ( @sort_cat ) {
  494.                 $e .= sprintf ( "|%${LEN}d", $DB{$host}{$cat}[0] );
  495.  
  496.                 if ( "$FORM_DATE" ne "none" ) {
  497.                     $d .= sprintf ( "|%${LEN}.${LEN}s",
  498.                         &fmt_date_ascii( $DB{$host}{$cat}[1] ) );
  499.                     }
  500.                 if ("$FORM_TIME" ne "none") {
  501.                     $t .= sprintf ( "|%${LEN}.${LEN}s",
  502.                         &fmt_time_ascii( $DB{$host}{$cat}[2] ) );
  503.                     }
  504.                 }
  505.             print Statfile "$e| $host\n";
  506.             if ( "$FORM_DATE" ne "none" )
  507.                 { print Statfile "$d|\n"; }
  508.             if ( "$FORM_TIME" ne "none" )
  509.                 { print Statfile "$t|\n"; }
  510.             }
  511.         else { # Orientation "besides"
  512.             $e = ''; $t = '';
  513.             foreach $cat ( @sort_cat ) {
  514.                 $d = sprintf ( "%4d", $DB{$host}{$cat}[0] );
  515.                 if ( $DB{$host}{$cat}[0] != 0 ) {
  516.                     if ( "$FORM_DATE" ne "none" ) {
  517.                         $d .= ',' . &fmt_date_ascii( $DB{$host}{$cat}[1] );
  518.                         if ( "$FORM_TIME" ne "none" ) {
  519.                             $t .= sprintf( "|%${LEN}.${LEN}s",
  520.                                 &fmt_time_ascii( $DB{$host}{$cat}[2] ) );
  521.                             }
  522.                         }
  523.                     else {
  524.                         if ("$FORM_TIME" ne "none") {
  525.                             $d .= ',' . &fmt_time_ascii( $DB{$host}{$cat}[2] );
  526.                             }
  527.                         }
  528.                     }
  529.                 else {
  530.                     if ( "$FORM_TIME" ne "none" && "$FORM_DATE" ne "none" )
  531.                         { $t .= sprintf ( "|%${LEN}.${LEN}s", " " ); }
  532.                     }
  533.                 $e .= sprintf ( "|%-${LEN}.${LEN}s", $d );
  534.                 }
  535.             print Statfile "$e| $host\n";
  536.             if ( "$FORM_TIME" ne "none" && "$FORM_DATE" ne "none" )
  537.                 { print Statfile "$t|\n"; }
  538.             }
  539.         if ( "$RULER" eq "on" )
  540.             { print Statfile "$rule\n"; }
  541.         }
  542.     if ( "$RULER" eq "off" ) # print ruler in last line of table
  543.         { print Statfile "$rule\n"; }
  544.     }
  545. else {
  546.     #---------------
  547.     # html output
  548.     #---------------
  549.     $rule = "<TR>$REMOTE_HEADER";
  550.     foreach $cat ( @sort_cat ) {
  551.         if ( "$ORIENTATION" eq "besides" && 
  552.             ( "$FORM_DATE" ne "none" || "$FORM_TIME" ne "none" ) )
  553.             { $rule .= "<TH COLSPAN=2 ${CATEGORY{$cat}[5]}</TH>"; }
  554.         else
  555.             { $rule .= "<TH ${CATEGORY{$cat}[5]}</TH>"; }
  556.         }
  557.     $rule .= "</TR>";
  558.  
  559.     foreach $host ( @sorted_hosts ) {
  560.         if ( $count == 0 )
  561.             { print Statfile "<TABLE BORDER>$rule\n"; }
  562.         if ( $PAGER_LINES && $count == $PAGER_LINES ) {
  563.             if ( "$RULER" eq "off" )
  564.                 { print Statfile "</TABLE><P>\n<TABLE BORDER>"; }
  565.             print Statfile "$rule\n";
  566.             $count = 0;
  567.             }
  568.         $count++;
  569.         print Statfile "<TR ALIGN=CENTER><TH ALIGN=LEFT>$host</TH>";
  570.         foreach $cat ( @sort_cat ) {
  571.             if ( $DB{$host}{$cat}[0] )
  572.                 { print Statfile "<TD>${DB{$host}{$cat}[0]}"; }
  573.             else
  574.                 { print Statfile '<TD> '; }
  575.  
  576.             if ( "$ORIENTATION" eq "below" ) {
  577.                 if ( "$FORM_DATE" ne "none" ) {
  578.                     $d = &fmt_date_html( $DB{$host}{$cat}[1] );
  579.                     print Statfile "<BR><FONT SIZE=\"-1\"><I>$d</I></FONT>";
  580.                     }
  581.                 if ( "$FORM_TIME" ne "none" ) {
  582.                     $d = &fmt_time_html( $DB{$host}{$cat}[2] );
  583.                     print Statfile "<BR><FONT SIZE=\"-1\"><I>$d</I></FONT>";
  584.                     }
  585.                 }
  586.             else { # Orientation besides
  587.                 if ( "$FORM_DATE" ne "none" ) {
  588.                     $d = &fmt_date_html( $DB{$host}{$cat}[1] );
  589.                     print Statfile "</TD><TD><FONT SIZE=\"-1\"><I>$d</I> ";
  590.                     }
  591.                 if ( "$FORM_TIME" ne "none" ) {
  592.                     $d = &fmt_time_html( $DB{$host}{$cat}[2] );
  593.                     if ( "$FORM_DATE" eq "none" ) {
  594.                         print Statfile "</TD><TD><FONT SIZE=\"-1\"><I>$d</I>";
  595.                         }
  596.                     else
  597.                         { print Statfile "<BR><FONT SIZE=\"-1\"><I>$d</I>"; }
  598.                     }
  599.                 }
  600.             print Statfile "</TD>";
  601.             }
  602.         print Statfile "</TR>\n";
  603.         }
  604.     print Statfile "</TABLE>\n";
  605.     }
  606.  
  607. #--------------------
  608. # trailer
  609. #--------------------
  610.  
  611. if ( "$OUTPUT" eq "ascii" ) {
  612.     foreach ( @ASCII_TRAILER ) {
  613.         eval "\$h = \"$_\";";
  614.         print Statfile "$h\n";
  615.         }
  616.     }
  617. elsif ( "$OUTPUT" eq "html" ) {
  618.     foreach ( @HTML_TRAILER ) {
  619.         eval "\$h = \"$_\";";
  620.         print Statfile "$h\n";
  621.         }
  622.     }
  623. close(Statfile);
  624. }
  625.  
  626. sub fmt_date_ascii {
  627.     local( $_ ) = @_;
  628.     local( $dd );
  629.     if ( "$FORM_DATE" eq "long" ) {
  630.         if ( /(\d*)\/(\d*)/ )
  631.             { $dd = sprintf ("%3.3s %2d", $MONTH_NUM_TO_STR[$1], $2 ); }
  632.         else
  633.             { $dd = '      '; }
  634.         }
  635.     else 
  636.         { $dd = sprintf ( "%5.5s", $_ ); }
  637.     $dd;
  638.     }
  639.  
  640. sub fmt_date_html {
  641.     local( $_ ) = @_;
  642.     local( $dd );
  643.     if ( "$FORM_DATE" eq "long" ) {
  644.         if ( /(\d*)\/(\d*)/ )
  645.             { $dd = $MONTH_NUM_TO_STR[$1] . ' ' . $2; }
  646.         else
  647.             { $dd = ' '; }
  648.         }
  649.     else {
  650.         if( /\S+/ )
  651.             { $dd = $_ ; }
  652.         else
  653.             { $dd = ' '; }
  654.         }
  655.     $dd;
  656.     }
  657.  
  658. sub fmt_time_ascii {
  659.     local( $_ ) = @_;
  660.     local( $tt );
  661.     if ( "$FORM_TIME" eq "long" )
  662.         { $tt = sprintf( "%8.8s", $_ ); }
  663.     else 
  664.         { $tt = sprintf( "%5.5s", $_ );}
  665.     $tt;
  666.     }
  667.  
  668. sub fmt_time_html {
  669.     local( $_ ) = @_;
  670.     local( $tt );
  671.     if ( /\S+/ ) {
  672.         if ( "$FORM_TIME" eq "long" )
  673.             { $tt = $_; }
  674.         else
  675.             { $tt = sprintf ("%5.5s", $_ ); }
  676.         }
  677.     else 
  678.         { $tt = ' '; }
  679.     $tt;
  680.     }
  681.  
  682. #-----------------------------------------
  683. # Help message
  684. #-----------------------------------------
  685.  
  686. sub help_screen {
  687.     &version_info;
  688.     print <<"EOF"
  689.  Tidy up logfile created by syslogd and do statistics on it
  690.  
  691.  Syntax: tidy [-B database] [-C configfile] [-L logfile] [-o outfile]
  692.               [-p pagerlines] [-s sortkey] [-abcDdHOqrTt] [+bcdOprt]
  693.          tidy -h | -v
  694.  
  695.  See manpage tidy(8) for a detailed description
  696.  
  697.  Author: Marek Rouchal (marek\@saftsack.fs.uni-bayreuth.de)
  698.  
  699. EOF
  700.     }
  701.  
  702. sub version_info {
  703.     print <<"EOF"
  704.  
  705.  This is tidy Version 1.0
  706.  
  707. EOF
  708.     }
  709.  
  710.